package owg.util.opengl.models;

import java.nio.FloatBuffer;
import java.util.ArrayList;


/**
 * A high performance renderable. Can either be a Vertex Buffer Object, a Vertex Array or a Display List.
 * The construction functions do not perform any OpenGL calls until end() is called.
 * Subclasses of this interface will use 32 bit float precision for all vertex data.
 * */
public abstract class HPRF extends HPRA<VertexFloat>
{
	float[] vData;
	
	/**Create a new HPRF with the given name, initial face mode and vertex attributes.
	 * The model will be initialized with no vertices and no indices.
	 * @param nVertexComps */
	public HPRF(String name, int faceMode, byte nVertexComps, boolean useNormal, byte nColorComps, byte nTexCoords, byte nTexCoords2)
	{
		super(name, faceMode, nVertexComps, useNormal, nColorComps, nTexCoords, nTexCoords2);
	}
	
	@Override
	protected void compileVDataFromList(ArrayList<VertexFloat> vertices)
	{
		if(vBuildMode == BUILD_ARRAYLIST)
		{
			//Create buffers and interleave data
			int totalNumVerts = vertices.size();
			vData = new float[totalNumVerts*vertexStride];
			FloatBuffer vBuf = FloatBuffer.wrap(vData);
			
			for(int i=0; i<totalNumVerts; i++)
			{
				VertexFloat v = vertices.get(i);
				v.put(vBuf, numVertexComponents, useNormal, numColorComponents, numTexCoordComponents, numTexCoordComponents2);
			}
		}
	}
	/**Return the backing vertex array in main memory.
	 * Use the returned array to change the vertex data. Call requestUpdate() when done.*/
	public final float[] getVData()
	{
		return vData;
	}
	/**Can be used to set the vertex data instead of adding Vertex objects, when building the HPR.
	 * This array will be kept by the HPRF implementation, and be the same as the result of getVData().
	 * It is illegal to call this method after a call to {@link #end()}. Create a new renderable, or
	 * modify the existing array through {@link HPRF#getVData()} and call {@link #requestVUpdate()}*/
	public final void setPrepackedVData(float[] data)
	{
		if(vBuildMode == BUILD_COMPLETED)
			throw new RuntimeException("Cannot set vData because the model has already been built!");
		vBuildMode = BUILD_PREPACKED;
		vData = data;
		
	}
}